include ../_util-fns

:marked
  We’ll write our tests with the [Jasmine test framework](http://jasmine.github.io/2.3/introduction.html).
  We’ll start by getting *some* tests to work - *any* tests at all.

  我们将使用[Jasmine测试框架](http://jasmine.github.io/2.3/introduction.html)来编写测试。
  先从让*某些*测试跑起来开始 —— *任何一个*测试都可以。

  We will learn

  我们会学到：

    - basic Jasmine testing skills

    - Jasmine测试的基础技能

    - to run our tests in the browser

    - 在浏览器里运行我们的测试

    - to write simple Jasmine tests in TypeScript

    - 用TypeScript编写简单的Jasmine测试

    - to debug a test in the browser

    - 在浏览器里调试一个测试

  **Create a new project folder** perhaps called `angular2-unit-testing`.

  **新建一个项目目录**，命名为`angular2-unit-testing`。

.l-main-section
:marked
  ## Install npm packages locally

  ## 本地安装npm包

  Next follow all of  the steps prescribed in  “Install npm packages locally” of the
  [QuickStart](../quickstart.html).

  接下来，完成[“快速起步”](../quickstart.html)一章中“本地安装npm包”的每一步。

  We’ll also add the Jasmine package via `npm`:

  然后我们通过`npm`添加Jasmine包：

pre.prettyprint.lang-bash
   code npm install jasmine-core --save-dev --save-exact

.alert.is-important
  :marked
    Be sure to install `jasmine-core` , not `jasmine`!

    请确保安装的是`jasmine-core`，而不是`jasmine`！

:marked
  **Create a sub-folder `src` ** for our tests and then **cd into it**.

  为这次测试**新建一个子目录`src`**，然后**cd进去**。

  We are going to **display and control our tests in the browser**.

  我们将会**在浏览器里显示和控制这些测试**。

.l-sub-section
  :marked
    The browser is nice during development of a few tests. It’s not the best venue for working with a lot of tests and it won’t do at all for build automation.
    We’ll switch to the karma test-runner when the time comes. But the browser will do for now.

    在我们开发某些测试的过程中，浏览器很有帮助。如果要写很多测试，它并不是最佳选择，更不用说用到自动化构建中了。
    等那时候我们就会切换到Karma测试运行器(test-runner)。但目前还是先用浏览器吧。

:marked
  Create a new file called`unit-tests.html` and enter the following:

  新建一个名叫`unit-tests.html`的文件，并输入如下内容：

+makeExample('testing/ts/unit-tests-0.html', 'no-script', 'unit-tests.html')

:marked
  In the head we have three Jasmine scripts and one Jasmine css file. That’s the foundation for running any tests.

  在`head`标记中有三个Jasmine脚本和一个Jasmine css文件。它们是运行任何测试的基础。

  We’ll write our first test with inline JavaScript inside the body tag:

  然后在`body`标记中，我们以内联JavaScript的形式编写第一个测试：

+makeExample('testing/ts/unit-tests-0.html', 'body')(format='.')

:marked
  Now open `unit-tests.html` in a browser and see the Jasmine HTML test output:

  现在，在浏览器中打开`unit-tests.html`，就能看到HTML格式的Jasmine测试结果：

figure.image-display
    img(src='/resources/images/devguide/jasmine-testing-101/jasmine-1-spec-0-failures.png' style="height:170px;" alt="Jasmine HTML test output")

:marked
  It doesn’t get much simpler than that!

  这已经简单得不能再简单了。

.l-main-section
:marked
  ## First TypeScript Test

  ## 第一个TypeScript测试

  Perhaps too simple. We won’t write our entire test suite inside one HTML file.
  Let’s **extract** that line of test code to a **new file in `src` called `1st.spec.ts` ** .

  也许简单得过头了。我们不会在HTML文件中编写测试套件。我们来把这些测试代码**提取**到**`src`目录下的新文件`1st.spec.ts`中**。

.l-sub-section
  :marked
    Among Jasmine developers, a test is known as a “spec” and test filenames include the word “spec”.  We’ll stick with that convention.

    在Jasmine开发者中，测试通常被叫做“规约(spec)”，而且测试文件的名字也会包含单词“spec”。我们也将遵循这个规则。

:marked
  The test we wrote is valid TypeScript because any JavaScript is valid TypeScript. But let’s make it more modern with an arrow function:

  我们写的这个测试也是一个有效的TypeScript，因为所有JavaScript都是有效的TypeScript。但TypeScript允许我们使用箭头函数来让它显得更有现代感：

+makeExample('testing/ts/1st.spec.ts', 'it', '1st.spec.ts')

:marked
  Now modify `unit-tests.html` to load the script:

  现在修改`unit-tests.html`以加载此脚本：

+makeExample('testing/ts/unit-tests-1.html', 'script')

:marked
  Hold on! We wrote a TypeScript file but we’re loading a JavaScript file?

  等等！我们刚写的明明是TypeScript文件，为何这里要加载JavaScript文件？

  That’s a reminder that we need to compile our TypeScript test files as we do our TypeScript application files.  Do that next.

  这是提醒我们要编译TypeScript测试文件，就像编译应用程序中的TypeScript文件那样。接下来我们就做这个。

.l-main-section
:marked
  ## Prepare for TypeScript

  ## 为TypeScript做准备

  As we’ve seen before, we first have to tell the compiler how to compile our TypeScript files with
  a ** `tsconfig.json` **.

  和以前见过的一样，我们必须用**`tsconfig.json`**文件告诉编译器如何编译我们的TypeScript文件。

  We can copy one from the quickstart we wrote previously and paste it into our src sub-folder.
  It should look something like this:

  我们可以从“快速起步”中拷贝一个写好的，粘贴到src子目录下，就像这样：

+makeExample('testing/ts/tsconfig.1.json', null, 'tsconfig.json')

:marked
  ## Compile and Run

  ## 编译和运行

  Compile in the terminal window using the npm script command

  在终端窗口，使用npm脚本命令进行编译：

pre.prettyprint.lang-bash
  code npm run tsc

.alert.is-helpful
  :marked
    Our editor and the compiler may complain that they don’t know
    what `it` and `expect` are because they lack the typing files that describe Jasmine.
    We can ignore those annoying complaints for now as they are harmless.

    我们的编辑器和编译器可能会抱怨说它们不认识`it`和`expect`，这是因为它们缺少Jasmine的类型定义文件。
    先暂且忽略这些抱怨，它们目前没有危害。

:marked
  If we reload the browser, we should see the same Jasmine test-runner output as before.

  如果刷新浏览器，我们就会看到跟以前一样的Jasmine测试运行器输出。

  We’ll be evolving these tests rapidly and it would be nice to have the browser refresh automatically as we make changes and recompile.

  我们希望这些测试能快速进化，如果浏览器能在我们做出修改和重新编译时自动刷新就好了。

  Let’s launch with **lite-server** in a second terminal window:

  没问题，让我们在另一个终端窗口中启动**lite-server**：

pre.prettyprint.lang-bash
  code npm start

:marked
  Now reload `unit-tests.html` in the browser

  在浏览器中刷新一下`unit-tests.html`

  We should get the same Jasmine test-runner output as before.

  我们应该能看到跟以前一样的Jasmine测试运行器输出。

.l-main-section
:marked
  ## Add a describe and another test

  ## 添加一个describe和其它测试

  We can’t tell what file produced these test results. We only have one file at the moment but soon we’ll write more.

  我们并不知道是哪个文件生成了这些测试结果。虽然目前我们只有一个文件但很快就会写更多文件。

  We should wrap this test into something that identifies the file. In Jasmine that “something” is a `describe` function.
  Every test file should have at least one `describe` that identifies the file holding the test(s).

  我们应该把这个测试包裹进一个可以标识出所属文件的东西中。在Jasmine领域，它就是`describe`函数。
  每个测试文件都至少得有一个`describe`语句来标识该文件测试了什么。

  Here’s what our revised `1st.spec.ts` looks like when wrapped in a `describe`:

  下面是我们修改后的`1st.spec.ts`，用`describe`包裹后是这样的：

+makeExample('testing/ts/1st.spec.ts', 'describe')

:marked
  And here’s how the test report displays it.

  下面是测试报告的显示内容：

figure.image-display
    img(src='/resources/images/devguide/jasmine-testing-101/test-report-1-spec-0-failures.png' style="height:100px;" alt="1 spec, 0 failures")

:marked
  Let’s add another Jasmine test to `1st.spec.ts`

  我们来向`1st.spec.ts`中添加另一个测试

+makeExample('testing/ts/1st.spec.ts', 'another-test')(format=".")

:marked
  You knew that right?  Let’s prove it with this test. The browser should refresh after you paste that test, and show:

  你知道这个，对吧？现在让我们用这个测试来证明它。在你粘贴完那个测试后，浏览器会刷新并显示为：

figure.image-display
    img(src='/resources/images/devguide/jasmine-testing-101/test-report-2-specs-0-failures.png' style="height:100px;" alt="refreshed 2 specs, 0 failures")

:marked
  What does a failing test look like? Remove the `.not`. The browser refreshes and shows:

  如果测试失败了会怎样？删除`.not`，浏览器会刷新并显示为：

figure.image-display
    img(src='/resources/images/devguide/jasmine-testing-101/test-report-2-specs-1-failure.png' style="height:190px;" alt="failing test 2 specs, 1 failure")

:marked
  Click the `Spec List` link just below “2 specs, 1 failure” to see the summary again:

  点击“2 Specs, 1 failure”下面的`Spec List`链接，再看看汇总信息：

figure.image-display
    img(src='/resources/images/devguide/jasmine-testing-101/spec-list-2-specs-1-failure.png' style="height:140px;" alt="2 specs, 1 failure")

:marked
  We can re-run just the failing test by double-clicking it.  Try it!

  我们可以只重新运行那个失败的测试，双击它就可以了。试试看!

.l-main-section
:marked
  ## Debug the test

  ## 调试那个测试

  Suppose we didn’t know what was going on.  We can debug it in the browser.

  假设我们不知道它为什么失败，就可以在浏览器中调试它。

    - Open the browser’s “Developer Tools” (F12 or Ctrl-Shift-I).

    - 打开浏览器的“开发者工具”(F12或者Ctrl-Shift-I)

    - Pick the “sources” section

    - 选择"sources"标签

    - Open the `1st.spec.ts` test file (Ctrl-P, then start typing the name of the file).

    - 打开测试文件`1st.spec.ts`(Ctrl-P, 然后开始输入文件名)

    - Set a breakpoint on the second line of the failing test

    - 在这个失败测试的第二行，设置一个断点

    - Refresh the browser and it stops at our breakpoint.

    - 刷新浏览器，然后它停在了我们的断点上

    - Open the console window at the bottom  (press Esc)

    - 打开底部的console窗口(按Esc键)

    - Type `null === undefined` and we should see this:

    - 输入`null === undefined`...然后我们可以看到这个：

figure.image-display
    img(src='/resources/images/devguide/jasmine-testing-101/null-to-equal-undefined.png' style="height:500px;" alt="null === undefined")

:marked
  How about that!  They really aren’t equal.

  怎么样？它们真的不相等。

    - remove the breakpoint (right-click in the “Breakpoints” section and chose “Remove breakpoint”)

    - 移除断点(在“Breakpoints”区域，右键点击“Remove breakpoint”)

    - Click the “play” icon to resume the test  (or F8)

    - 点“play”图标继续运行测试(或F8)

  And the test finishes.  Close the browser tools (click the close box or press F12 or Ctrl-Shift-I)

  这样测试就算完成了。关闭浏览器工具(点击关闭图标或者按F12或Ctrl-Shift-I)

  Fix the test (restore the `.not`);  the browser should refresh automatically and all tests pass.

  修复测试(还原`.not`)；浏览器会自动刷新，所有测试都通过了。

  Congratulations, you’ve completed Jasmine testing 101.

  恭喜...你完成了Jasmine测试简介。

  Now that we’re familiar with Jasmine on its own, we’re ready to test an application.

  现在，我们已经熟悉了Jasmine本身，接下来就要开始测试应用程序了。

  <!-- TODO
  .l-main-section
  :marked
    ## Learn more
    Learn more about basic Jasmine testing here
    [Resources TBD](./#)
    -->
